﻿using Microsoft.Extensions.Logging;
using RotovapPlatform.Domain.Equipment.Device.Motors.Dto;
using RotovapPlatform.Domain.Equipment.Interfaces.Base;
using RotovapPlatform.Domain.Equipment.Interfaces.Services;
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows.Input;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Threading;

namespace RotovapPlatform.UI.ViewModels.DeviceMaintenance.ManualOperation
{
	public partial class MotorControlViewModel : ObservableObject, IDisposable
	{
		private readonly IMotorControlService _motorControlService;
		private readonly ILogger<MotorControlViewModel> _logger;
		private bool _isInitialized;
		private bool _disposed;
		private CancellationTokenSource _statusUpdateCts;

		[ObservableProperty]
		[NotifyCanExecuteChangedFor(nameof(EnableMotorCommand))]
		[NotifyCanExecuteChangedFor(nameof(DisableMotorCommand))]
		[NotifyCanExecuteChangedFor(nameof(HomeMotorCommand))]
		[NotifyCanExecuteChangedFor(nameof(JogPlusCommand))]
		[NotifyCanExecuteChangedFor(nameof(JogMinusCommand))]
		[NotifyCanExecuteChangedFor(nameof(StopMotorCommand))]
		[NotifyCanExecuteChangedFor(nameof(MoveToPositionCommand))]
		[NotifyCanExecuteChangedFor(nameof(ResetAxisCommand))]
		private IMotorBase _selectedMotor;

		[ObservableProperty]
		private MotorStatus _motorStatus;

		[ObservableProperty]
		[NotifyCanExecuteChangedFor(nameof(MoveToPositionCommand))]
		private string _selectedPosition;

		[ObservableProperty]
		private ObservableCollection<IMotorBase> _motors = new();

		[ObservableProperty]
		private ObservableCollection<string> _workPositions = new();

		[ObservableProperty]
		private bool _isLoading;

		public MotorControlViewModel(
			IMotorControlService motorControlService,
			ILogger<MotorControlViewModel> logger)
		{
			_motorControlService = motorControlService;
			_logger = logger;

			// 启动异步初始化
			_ = InitializeAsync();
		}

		partial void OnSelectedMotorChanged(IMotorBase value)
		{
			// 如果之前有状态更新循环，确保停止
			if (value == null && _statusUpdateCts != null)
			{
				try
				{
					if (!_statusUpdateCts.IsCancellationRequested)
					{
						_statusUpdateCts.Cancel();
					}
				}
				catch (ObjectDisposedException)
				{
					// 已经被处置，忽略异常
					_logger?.LogDebug("取消已处置的CancellationTokenSource");
				}
			}

			if (value != null)
			{
				_logger.LogInformation($"选中电机: {value.Name} (ID: {value.EquipmentId})");
				LoadWorkPositions(value.EquipmentId);
				StartStatusUpdateLoop();
			}
			else
			{
				_logger.LogInformation("未选中电机");
			}
		}

		partial void OnSelectedPositionChanged(string value)
		{
			_logger.LogInformation($"工作位置已更改为: {value ?? "null"}");
			MoveToPositionCommand.NotifyCanExecuteChanged();
		}

		private async Task InitializeAsync()
		{
			try
			{
				IsLoading = true;
				_logger.LogInformation("开始初始化电机控制视图模型");

				var motors = await _motorControlService.GetMotorsAsync();
				Motors.Clear();
				foreach (var motor in motors)
				{
					Motors.Add(motor);
					_logger.LogInformation($"添加电机: {motor.Name} (ID: {motor.EquipmentId})");
				}

				_isInitialized = true;
				_logger.LogInformation($"电机控制视图模型初始化完成，共加载 {Motors.Count} 个电机");

				// 通知所有命令重新评估其 CanExecute 状态
				EnableMotorCommand.NotifyCanExecuteChanged();
				DisableMotorCommand.NotifyCanExecuteChanged();
				HomeMotorCommand.NotifyCanExecuteChanged();
				JogPlusCommand.NotifyCanExecuteChanged();
				JogMinusCommand.NotifyCanExecuteChanged();
				StopMotorCommand.NotifyCanExecuteChanged();
				MoveToPositionCommand.NotifyCanExecuteChanged();
				ResetAxisCommand.NotifyCanExecuteChanged();
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "初始化电机控制视图模型时发生错误");
			}
			finally
			{
				IsLoading = false;
			}
		}

		private async void LoadWorkPositions(string motorId)
		{
			try
			{
				WorkPositions.Clear();
				var positions = await _motorControlService.GetMotorPositionsAsync(motorId);
				foreach (var position in positions)
				{
					WorkPositions.Add(position);
				}
				_logger.LogInformation($"已加载电机 {motorId} 的工作位置，共 {positions.Count()} 个");

				// 如果有工作位置，默认选择第一个
				if (WorkPositions.Count > 0)
				{
					SelectedPosition = WorkPositions[0];
					_logger.LogInformation($"默认选择工作位置: {SelectedPosition}");
				}
				else
				{
					SelectedPosition = null;
					_logger.LogInformation("没有可用的工作位置");
				}
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"加载电机 {motorId} 的工作位置时发生错误");
			}
		}

		private async void StartStatusUpdateLoop()
		{
			try
			{
				// 先检查并安全地处理之前的CTS
				if (_statusUpdateCts != null)
				{
					// 尝试取消，但要捕获可能的ObjectDisposedException
					try
					{
						if (!_statusUpdateCts.IsCancellationRequested)
						{
							_statusUpdateCts.Cancel();
						}
					}
					catch (ObjectDisposedException)
					{
						// CTS已经被处置，忽略异常
						_logger.LogDebug("尝试取消已处置的CancellationTokenSource");
					}

					// 释放之前的CTS
					try
					{
						_statusUpdateCts.Dispose();
					}
					catch (ObjectDisposedException)
					{
						// 已经被处置，忽略
					}
				}

				// 创建新的CTS
				_statusUpdateCts = new CancellationTokenSource();
				var token = _statusUpdateCts.Token;

				while (SelectedMotor != null && !token.IsCancellationRequested && !_disposed)
				{
					try
					{
						MotorStatus = await _motorControlService.GetMotorStatusAsync(SelectedMotor.EquipmentId);
						await Task.Delay(100, token);
					}
					catch (TaskCanceledException)
					{
						// 任务被取消，退出循环
						break;
					}
					catch (OperationCanceledException)
					{
						// 操作被取消，退出循环
						break;
					}
					catch (ObjectDisposedException)
					{
						// CTS已被处置，退出循环
						_logger.LogDebug("状态更新期间CTS已被处置");
						break;
					}
					catch (Exception ex)
					{
						_logger.LogError(ex, "更新电机状态时发生错误");
						break;
					}
				}
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "状态更新循环异常");
			}
		}

		private bool CanExecuteMotorCommand()
		{
			var canExecute = SelectedMotor != null && _isInitialized;
			_logger.LogDebug($"检查电机命令执行条件: 选中电机={SelectedMotor != null}, 已初始化={_isInitialized}, 结果={canExecute}");
			return canExecute;
		}

		private bool CanExecuteMoveToPosition()
		{
			var motorReady = CanExecuteMotorCommand();
			var positionSelected = !string.IsNullOrEmpty(SelectedPosition);
			var canExecute = motorReady && positionSelected;

			_logger.LogDebug($"检查移动到位置命令执行条件: 电机就绪={motorReady}, 选中位置={SelectedPosition ?? "未选择"}, 结果={canExecute}");

			return canExecute;
		}

		[RelayCommand(CanExecute = nameof(CanExecuteMotorCommand))]
		private async Task EnableMotorAsync()
		{
			try
			{
				await _motorControlService.EnableMotorAsync(SelectedMotor.EquipmentId);
				_logger.LogInformation($"电机 {SelectedMotor.Name} 使能成功");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"电机 {SelectedMotor.Name} 使能失败");
			}
		}

		[RelayCommand(CanExecute = nameof(CanExecuteMotorCommand))]
		private async Task DisableMotorAsync()
		{
			try
			{
				await _motorControlService.DisableMotorAsync(SelectedMotor.EquipmentId);
				_logger.LogInformation($"电机 {SelectedMotor.Name} 去使能成功");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"电机 {SelectedMotor.Name} 去使能失败");
			}
		}

		[RelayCommand(CanExecute = nameof(CanExecuteMotorCommand))]
		private async Task HomeMotorAsync()
		{
			try
			{
				await _motorControlService.HomeMotorAsync(SelectedMotor.EquipmentId);
				_logger.LogInformation($"电机 {SelectedMotor.Name} 回零成功");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"电机 {SelectedMotor.Name} 回零失败");
			}
		}

		[RelayCommand(CanExecute = nameof(CanExecuteMotorCommand))]
		private async Task JogPlusAsync()
		{
			try
			{
				await _motorControlService.JogPlusAsync(SelectedMotor.EquipmentId);
				_logger.LogInformation($"电机 {SelectedMotor.Name} JOG+成功");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"电机 {SelectedMotor.Name} JOG+失败");
			}
		}

		[RelayCommand(CanExecute = nameof(CanExecuteMotorCommand))]
		private async Task JogMinusAsync()
		{
			try
			{
				await _motorControlService.JogMinusAsync(SelectedMotor.EquipmentId);
				_logger.LogInformation($"电机 {SelectedMotor.Name} JOG-成功");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"电机 {SelectedMotor.Name} JOG-失败");
			}
		}

		[RelayCommand(CanExecute = nameof(CanExecuteMotorCommand))]
		private async Task StopMotorAsync()
		{
			try
			{
				_logger.LogInformation("正在停止电机 {MotorId}", SelectedMotor.EquipmentId);
				await _motorControlService.StopMotorAsync(SelectedMotor.EquipmentId);
				_logger.LogInformation("电机 {MotorId} 已停止", SelectedMotor.EquipmentId);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "停止电机 {MotorId} 时发生错误", SelectedMotor?.EquipmentId);
			}
		}

		[RelayCommand(CanExecute = nameof(CanExecuteMotorCommand))]
		private async Task ResetAxisAsync()
		{
			try
			{
				_logger.LogInformation("正在复位轴 {MotorId}", SelectedMotor.EquipmentId);
				await _motorControlService.ResetAxisAsync(SelectedMotor.EquipmentId);
				_logger.LogInformation("轴 {MotorId} 已复位", SelectedMotor.EquipmentId);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "复位轴 {MotorId} 时发生错误", SelectedMotor?.EquipmentId);
			}
		}

		/// <summary>
		/// 开始JOG+运动（按下按钮时调用）
		/// </summary>
		public async void StartJogPlus()
		{
			if (SelectedMotor == null || !_isInitialized)
				return;

			try
			{
				await _motorControlService.JogPlusAsync(SelectedMotor.EquipmentId);
				_logger.LogInformation($"开始电机 {SelectedMotor.Name} JOG+运动");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"电机 {SelectedMotor.Name} JOG+启动失败");
			}
		}

		/// <summary>
		/// 开始JOG-运动（按下按钮时调用）
		/// </summary>
		public async void StartJogMinus()
		{
			if (SelectedMotor == null || !_isInitialized)
				return;

			try
			{
				await _motorControlService.JogMinusAsync(SelectedMotor.EquipmentId);
				_logger.LogInformation($"开始电机 {SelectedMotor.Name} JOG-运动");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"电机 {SelectedMotor.Name} JOG-启动失败");
			}
		}

		/// <summary>
		/// 停止JOG运动（松开按钮时调用）
		/// </summary>
		public async void StopJog()
		{
			if (SelectedMotor == null || !_isInitialized)
				return;

			try
			{
				await _motorControlService.StopMotorAsync(SelectedMotor.EquipmentId);
				_logger.LogInformation($"停止电机 {SelectedMotor.Name} JOG运动");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"电机 {SelectedMotor.Name} JOG停止失败");
			}
		}

		[RelayCommand(CanExecute = nameof(CanExecuteMoveToPosition))]
		private async Task MoveToPositionAsync()
		{
			try
			{
				await _motorControlService.MoveToPositionAsync(SelectedMotor.EquipmentId, SelectedPosition);
				_logger.LogInformation($"电机 {SelectedMotor.Name} 移动到位置 {SelectedPosition} 成功");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"电机 {SelectedMotor.Name} 移动到位置 {SelectedPosition} 失败");
			}
		}

		/// <summary>
		/// 释放资源
		/// </summary>
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		/// <summary>
		/// 释放资源
		/// </summary>
		/// <param name="disposing">是否为显式释放</param>
		protected virtual void Dispose(bool disposing)
		{
			if (_disposed) return;

			if (disposing)
			{
				// 取消状态更新循环
				if (_statusUpdateCts != null)
				{
					try
					{
						if (!_statusUpdateCts.IsCancellationRequested)
						{
							_statusUpdateCts.Cancel();
						}
						_statusUpdateCts.Dispose();
						_statusUpdateCts = null;
					}
					catch (ObjectDisposedException)
					{
						// 已经被处置，忽略异常
						_logger?.LogDebug("在Dispose中处理已处置的CancellationTokenSource");
					}
					catch (Exception ex)
					{
						_logger?.LogError(ex, "处置CancellationTokenSource时发生错误");
					}
				}

				_logger?.LogInformation("MotorControlViewModel已取消状态更新循环");
			}

			_disposed = true;
		}

		/// <summary>
		/// 重新初始化ViewModel，用于视图重新加载时
		/// </summary>
		public void Reinitialize()
		{
			try
			{
				_logger?.LogInformation("正在重新初始化MotorControlViewModel");

				// 如果已释放，则重置状态
				if (_disposed)
				{
					_disposed = false;
				}

				// 如果未初始化，重新初始化
				if (!_isInitialized)
				{
					_ = InitializeAsync();
				}
				// 如果之前有选中的电机，重新启动状态更新
				else if (SelectedMotor != null)
				{
					StartStatusUpdateLoop();
				}

				_logger?.LogInformation("MotorControlViewModel重新初始化完成");
			}
			catch (Exception ex)
			{
				_logger?.LogError(ex, "重新初始化MotorControlViewModel失败");
			}
		}
	}
}